前言
昨天我們把「賽博紓壓診所」的 HTML 骨架搭好了。但老實說,打開瀏覽器一看,白底黑字的畫面看起來簡直就像遠古時代的佈告欄,完全跟「賽博(Cyber)」這兩個字沾不上邊。
身為一個每天看螢幕超過八小時的現代學生(特別是三更半夜趕專題的時候),「深色模式」絕對是救贖靈魂與眼睛的絕對必要功能!
如果以前要寫日夜切換,我可能會直覺用 JavaScript 抓出每個 class,然後痛苦地逐一改背景色和字色。但這次既然是做純前端專案,我想用更乾淨、更標準的做法:利用原生 CSS 變數搭配自訂屬性,完全不用寫兩套重複的排版樣式,就能一秒換膚!
核心觀念:為什麼 CSS 變數這麼好用?
簡單來說,我們可以在 :root(最頂層)把全站會用到的色彩先存成變數,例如 --bg-color 代表背景色、--card-bg 代表卡片顏色、--primary-color 代表診所的主色藍色(自設定為藍色)。
當網頁切換到暗色模式時,排版結構、卡片邊框、圓角、間距完全不用動,只需要把這幾個變數對應的顏色數值換成深灰色或黑色就可以了!再搭配一行 transition: background 0.3s, color 0.3s;,畫面切換時就會有很柔和的淡入淡出感,不會閃瞎雙眼。
動手寫 Code(上):CSS 變數宣告與樣式設計
首先,我們在網頁的頭部樣式區域寫入 CSS。這部分我們定義了日夜模式的變數對應,以及基礎的卡片與按鈕樣式:
/* 2. 當 html 標籤帶有 data-theme="dark" 時,覆蓋變數數值 */
[data-theme="dark"] {
--bg-color: #121212;
--card-bg: #1e1e1e;
--primary-color: #64b5f6;
--primary-hover: #42a5f5;
--text-main: #e0e0e0;
--text-muted: #9e9e9e;
}
/* 全域樣式:設定柔和轉場效果 */
body {
font-family: 'Segoe UI', Microsoft JhengHei, sans-serif;
background: var(--bg-color);
color: var(--text-main);
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow-x: hidden;
transition: background 0.3s, color 0.3s;
}
.container {
width: 100%;
max-width: 600px;
padding: 20px;
position: relative;
z-index: 10;
}
/* 診所主卡片 */
.card {
background-color: var(--card-bg);
border-radius: var(--border-radius);
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.15);
padding: 30px;
text-align: center;
position: relative;
transition: background-color 0.3s;
}
/* 頂部列:切換主題按鈕 */
.top-bar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
font-size: 0.85rem;
color: var(--text-muted);
}
h1 {
font-size: 1.5rem;
color: var(--primary-color);
margin-bottom: 10px;
}
p {
color: var(--text-muted);
font-size: 0.95rem;
margin-bottom: 20px;
}
/* 質感按鈕樣式 */
.btn {
background-color: var(--primary-color);
color: white;
border: none;
border-radius: 50px;
padding: 12px 30px;
font-size: 1rem;
cursor: pointer;
transition: background 0.2s, transform 0.1s;
box-shadow: 0 4px 15px rgba(30, 136, 229, 0.3);
width: 100%;
margin-top: 10px;
}
.btn:hover {
background-color: var(--primary-hover);
transform: translateY(-2px);
}
/* 隱藏區塊 */
.hidden {
display: none;
}
</style>
動手寫 Code(下):HTML 結構與 JavaScript 切換邏輯
接著是下半部分,我們把四大畫面區塊放進網頁主體區域裡,並在最下方寫入控制日夜切換的 JavaScript 函式:
<!-- 最外層容器 -->
<div class="container">
<!-- 1. 首頁區塊 -->
<div id="welcome-screen" class="card">
<div class="top-bar">
<span>✨ 賽博紓壓診所</span>
<!-- 日夜模式切換按鈕 -->
<button onclick="toggleTheme()" id="theme-btn" style="padding: 4px 10px; border-radius: 6px; cursor: pointer; background: var(--bg-color); color: var(--text-main); border: 1px solid #ccc;">
🌙 暗色
</button>
</div>
<h1>🧠 賽博紓壓診所與解碼器</h1>
<p>結合廟宇抽籤、六角形能力雷達圖、心電圖暴走與惡搞病歷處方籤的頂級心靈小工具。</p>
<button class="btn" id="btn-start" onclick="goToBreathe()">進入紓壓診所</button>
</div>
<!-- 2. 深呼吸過場區塊(預設隱藏) -->
<div id="breathe-screen" class="card hidden">
<h2>🧘 調整呼吸,放鬆心情</h2>
<div id="breathe-text" style="margin: 20px 0; font-weight: bold; color: var(--primary-color);">吸氣...</div>
</div>
<!-- 3. 測驗區塊(預設隱藏) -->
<div id="quiz-screen" class="card hidden">
<h2 id="question-text">題目載入中...</h2>
<div id="options-container"></div>
</div>
<!-- 4. 結果報告區塊(預設隱藏) -->
<div id="result-screen" class="card hidden">
<h1>🏥 賽博病歷診斷報告</h1>
<div id="score-display" style="font-size: 2rem; color: var(--primary-color);">0%</div>
<button class="btn" id="btn-restart" onclick="restartQuiz()">重新掛號測驗</button>
</div>
</div>
<script>
// 日夜模式切換邏輯
function toggleTheme() {
const html = document.documentElement;
const btn = document.getElementById('theme-btn');
// 判斷目前是否有 dark 屬性
if (html.getAttribute('data-theme') === 'dark') {
html.removeAttribute('data-theme');
btn.innerText = "🌙 暗色";
} else {
html.setAttribute('data-theme', 'dark');
btn.innerText = "☀️ 亮色";
}
}
// 單頁畫面切換測試
function goToBreathe() {
document.getElementById('welcome-screen').classList.add('hidden');
document.getElementById('breathe-screen').classList.remove('hidden');
}
function restartQuiz() {
document.getElementById('result-screen').classList.add('hidden');
document.getElementById('welcome-screen').classList.remove('hidden');
}
</script>
開發小踩坑與心態分享
老實說,在剛調這組色彩的時候,暗色模式下的文字對比度一度太低,整個畫面灰濛濛的一片,在昏暗環境下看得很吃力;但如果把背景直接調成純黑(#000000),又會顯得對比太強、看久了反而眼睛很累。
後來我採用了深淺適中的灰階(背景用 #121212,卡片用 #1e1e1e),再把主視覺的深藍換成較明亮柔和的天藍色(#64b5f6),整個舒適度就出來了!透過 CSS 變數的寫法,未來如果想換別的主題配色,只要改這幾行數值就搞定了,維護起來超省心!
今日結語與明日預告
今天我們利用 CSS 變數幫網頁穿上了可以隨時變裝的外衣,不只版面變漂亮了,還順便解鎖了現代網頁不可或缺的 Dark Mode!
明天,Day 04:不依賴套件!用 CSS Animation 刻出流暢的呼吸燈過場動畫,我會帶大家來實作進入測驗前的過場動畫,透過圓圈的放大縮小跟柔和色彩,幫使用者在正式測驗前先把緊張的心情放鬆下來。我們明天見!